package com.github.cooingandwooing.uaa.web.rest;

import javax.validation.Valid;

import com.github.cooingandwooing.uaa.config.AppProperties;
import com.github.cooingandwooing.uaa.domain.User;
import com.github.cooingandwooing.uaa.domain.dto.RegisterDto;
import com.github.cooingandwooing.uaa.domain.dto.TotpVerificationDto;
import com.github.cooingandwooing.uaa.exception.BadCredentialProblem;
import com.github.cooingandwooing.uaa.exception.NullException;
import com.github.cooingandwooing.uaa.service.UserCacheService;
import com.github.cooingandwooing.uaa.service.UserService;
import com.github.cooingandwooing.uaa.service.validation.UserValidationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/authorize")
public class AuthorizeResource {

    private final UserService userService;
    private final UserCacheService userCacheService;
    private final UserValidationService userValidationService;

    @GetMapping("/validation/username")
    public boolean validateUsername(@RequestParam String username) {
        return userValidationService.isUsernameExisted(username);
    }

    @GetMapping("/validation/email")
    public boolean validateEmail(@RequestParam String email) {
        return userValidationService.isEmailExisted(email);
    }

    @GetMapping("/validation/mobile")
    public boolean validateMobile(@RequestParam String mobile) {
        return userValidationService.isMobileExisted(mobile);
    }

    @PostMapping("/register")
    public void register(@Valid @RequestBody RegisterDto registerDto) throws NullException {
        // TODO 统一异常处理空值
        userValidationService.validateUserUniqueFields(registerDto.getUsername(), registerDto.getEmail(), registerDto.getMobile());
        val user = User.builder()
                .username(registerDto.getUsername())
                .name(registerDto.getName())
                .email(registerDto.getEmail())
                .mobile(registerDto.getMobile())
                .password(registerDto.getPassword())
                .usingMfa(false)
                .enabled(false)
                .build();
        userService.register(user);
    }

    @PostMapping("/totp")
    public void verifyTotp(@Valid @RequestBody TotpVerificationDto totpVerificationDto) {
        // TODO 待删除
        userCacheService.verifyTotp(totpVerificationDto.getMfaId(), totpVerificationDto.getCode())
                .orElseThrow(() -> new BadCredentialProblem());
    }

}
